/* Copyright (c) 2004-2022 peigen.info. All rights reserved. */

package info.peigen.hotpot.common.core.enums;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.annotation.JSONType;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <b>(BankCode)</b>
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2021/9/7
 */
@Getter
@NoArgsConstructor
@AllArgsConstructor
@JSONType(writeEnumAsJavaBean = true)
public enum BankCode implements Messageable {
    /** 为了对抗 Alibaba Java Coding 而存在的注释 */
    ICBC("ICBC", "工商银行", "102100099996", "ICBC"),
    BOC("BOC", "中国银行", "104100000004", "BOC"),
    CCB("CCB", "建设银行", "105100000017", "CCB"),
    CITIC("CITIC", "中信银行", "302100011000", "CITIC"),
    CEB("CEB", "光大银行", "303100000006", "CEB"),
    ABC("ABC", "农业银行", "103100000026", "ABC"),
    CIB("CIB", "兴业银行", "309391000011", "CIB"),
    CMB("CMB", "招商银行", "308584000013", "CMB"),
    CMBC("CMBC", "民生银行", "305100000013", "CMBC"),
    COMM("COMM", "交通银行", "301290000007", "BOCOM"),
    CQRCB("CQRCB", "重庆农村商业银行", "314653000011", "88000344"),
    HXB("HXB", "华夏银行", "304100040000", "HXB"),
    SPDB("SPDB", "浦发银行", "310290000013", "SPDB"),
    PSBC("PSBC", "邮政储蓄银行", "403100000004", "PSBC"),
    PINGANBK("PINGANBK", "平安银行", "307584007998", "PINGAN"),
    DBS_HK("DBS_HK", "星展银行-香港", "", ""),
    IBOC_CHICAGO("IBOC_CHICAGO", "国际银行-芝加哥", "", ""),
    ICBC_QIANHAI("ICBC_QIANHAI", "工商银行-前海分行", "", ""),
    CZCB_YIWU("CZCB_YIWU", "稠州银行-义乌分行", "", ""),
    CZCB("CZCB", "浙江稠州商业银行", "", "CZCB"),
    /** 不晓得啷格回事 */
    UNKNOWN("--", "不晓得啷格回事", "", ""),
    ;

    /** 枚举值 */
    String code;

    /** 枚举描述 */
    String message;

    /**
     * ICBC 银行代码
     */
    String icbcCode;

    /** 汇付天下 代码 */
    String huifuCode;

    /**
     * 通过枚举<code>code</code>获得枚举
     *
     * @param code 枚举值
     *
     * @return BankCode
     */

    public static BankCode getByCode(String code) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equals(code, innerEnum.code()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 通过枚举<code>name</code>获得枚举
     *
     * @param name 枚举名
     *
     * @return BankCode
     */
    public static BankCode getByName(String name) {
        return Stream.of(values())
                .filter(innerEnum -> StrUtil.equalsIgnoreCase(name, innerEnum.name()))
                .findFirst().orElse(UNKNOWN);
    }

    /**
     * 获取一个随机枚举
     *
     * @return BankCode
     */
    public static BankCode getRandomEnum() {
        return RandomUtil.randomEle(Stream.of(values()).filter(v -> v != UNKNOWN).toList());
    }

    /**
     * 获取一个随机枚举
     *
     * @param ignores 忽略几个枚举
     *
     * @return BankCode
     */
    public static BankCode getRandomEnum(BankCode... ignores) {
        return RandomUtil.randomEle(Stream.of(values()).filter(v -> !CollUtil.contains(Arrays.asList(ignores), v)).toList());
    }

    /**
     * 获取全部枚举
     *
     * @return List<BankCode>
     */
    public static List<BankCode> getAllEnum() {
        return Lists.newArrayList(values());
    }

    /**
     * 获取全部枚举值
     *
     * @return List<String>
     */
    public static List<String> getAllEnumCode() {
        return getAllEnum().stream().map(BankCode::code).collect(Collectors.toList());
    }

    /**
     * 通过code获取msg
     *
     * @param code 枚举值
     *
     * @return String
     */
    public static String getMsgByCode(String code) {
        return getByCode(code).message();
    }

    /**
     * 获取枚举code
     *
     * @param innerEnum 枚举
     *
     * @return code
     */
    public static String getCode(BankCode innerEnum) {
        return Optional.ofNullable(innerEnum).map(BankCode::code).orElse(UNKNOWN.code());
    }

    /**
     * map
     *
     * @return Map
     */
    public static Map<String, String> maps() {
        return Stream.of(values()).collect(Collectors.toMap(BankCode::code, BankCode::message));
    }

    /**
     * 判断给定的枚举，是否在列表中
     *
     * @param values 列表
     *
     * @return boolean
     */
    public boolean isInList(BankCode... values) {
        for (BankCode e : values) {
            if (this == e) {
                return true;
            }
        }
        return false;
    }

    /**
     * @return Returns the code.
     */
    @Override
    public String code() {
        return code;
    }

    /**
     * @return Returns the message.
     */
    @Override
    public String message() {
        return message;
    }
}